﻿using System;
using System.Linq;
using System.Web.Mvc;
using Localization;
using SinBiota.Model.Business.PersistenceServices.Interfaces;
using SinBiota.Model.Business.StatisticsServices.Interfaces;
using Sinbiota.Web.Models;

namespace Sinbiota.Web.Controllers
{
    public class StatisticsController : BaseController
    {
        private readonly ISinbiotaStatistics _sinbiotaStatistics;
        private readonly IOccurrenceStatistics _occurrenceStatistics;
        private readonly ISpeciesStatistics _speciesStatistics;
        private readonly IOccurrencePersistenceServices _occurrencePersistenceServices;

        public StatisticsController(ISinbiotaStatistics sinbiotaStatistics, IOccurrenceStatistics occurrenceStatistics, ISpeciesStatistics speciesStatistics, IOccurrencePersistenceServices occurrencePersistenceServices)
        {
            _sinbiotaStatistics = sinbiotaStatistics;
            _occurrencePersistenceServices = occurrencePersistenceServices;
            _speciesStatistics = speciesStatistics;
            _occurrenceStatistics = occurrenceStatistics;
        }

        //
        // GET: /Statistics/

        public ActionResult Index()
        {
            return View(CreateStatisticsPageModel());
        }


        public ActionResult GetOccurrenceStatistics(OccurrenceStatisticsType occurrenceStatisticsType)
        {
            switch (occurrenceStatisticsType)
            {
                case OccurrenceStatisticsType.OccurrencesByAmbient:
                    return OccurrencesByAmbient();
                case OccurrenceStatisticsType.OccurrencesByDrainageBasin:
                    return OccurrencesByDrainageBasin();
                case OccurrenceStatisticsType.OccurrencesByMunicipality:
                    return OccurrencesByMunicipality();
                case OccurrenceStatisticsType.OccurrencesByTaxonomicGroup:
                    return OccurrencesByTaxonomicGroup();
                case OccurrenceStatisticsType.OccurrencesByMonthYear:
                    return OccurrencesByMonthYear();
                case OccurrenceStatisticsType.OccurrencesByConservationUnit:
                    return OccurrencesByConservationUnit();
            }
            return Content("Not Implemented:" + occurrenceStatisticsType);
        }

        public ActionResult GetSpeciesStatistics(SpeciesStatisticsType speciesStatisticsType)
        {
            switch (speciesStatisticsType)
            {
                case SpeciesStatisticsType.SpeciesByAmbient:
                    return SpeciesByAmbient();
                case SpeciesStatisticsType.SpeciesByDrainageBasin:
                    return SpeciesByDrainageBasin();
                case SpeciesStatisticsType.SpeciesByMonthYear:
                    return SpeciesByMonthYear();
                case SpeciesStatisticsType.SpeciesByMunicipality:
                    return SpeciesByDrainageMunicipality();
                case SpeciesStatisticsType.SpeciesByTaxonomicGroup:
                    return SpeciesByTaxonomicGroup();
                case SpeciesStatisticsType.SpeciesByConservationUnit:
                    return SpeciesByConservationUnit();
                case SpeciesStatisticsType.Top10Species:
                    return Top10Species();
            }
            return Content("Not Implemented:" + speciesStatisticsType);
        }

        private ActionResult Top10Species()
        {
            var d = _occurrencePersistenceServices.Top10Species().ToDictionary(x => x.Key, x => x.Value);
            return PartialView("DisplayTemplates/DictionaryTable", new DictionaryTable(d, Strings.Species, Strings.Specimens));
        }

        private ActionResult SpeciesByConservationUnit()
        {
            var d = _occurrencePersistenceServices.SpeciesByConservationUnit().ToDictionary(x => x.Key, x => x.Value);
            return PartialView("DisplayTemplates/DictionaryTable", new DictionaryTable(d, Strings.ConservationUnit, Strings.SpeciesPlural));
        }

        private ActionResult SpeciesByTaxonomicGroup()
        {
            return PartialView("DisplayTemplates/DictionaryTable", new DictionaryTable(_occurrencePersistenceServices.SpeciesByTaxonomicGroup()
                .ToDictionary(x => x.Key, x => x.Value), Strings.TaxonomicGroup, Strings.SpeciesPlural));
        }

        private ActionResult SpeciesByDrainageMunicipality()
        {
            return PartialView("DisplayTemplates/DictionaryTable", new DictionaryTable(_occurrencePersistenceServices.SpeciesByMunicipality().ToDictionary(x => x.Key, x => x.Value),
                Strings.Municipality, Strings.SpeciesPlural));
        }

        private ActionResult SpeciesByMonthYear()
        {
            return PartialView("DisplayTemplates/DictionaryTable", new DictionaryTable(_occurrencePersistenceServices.SpeciesByMonthYear(), Strings.MonthYear, Strings.SpeciesPlural));
        }

        private ActionResult SpeciesByDrainageBasin()
        {
            return PartialView("DisplayTemplates/DictionaryTable", new DictionaryTable(_occurrencePersistenceServices.SpeciesByDrainageBasin().ToDictionary(x => x.Key, x => x.Value),
                Strings.DrainageBasin, Strings.SpeciesPlural));
        }

        private ActionResult SpeciesByAmbient()
        {
            return PartialView("DisplayTemplates/DictionaryTable", new DictionaryTable(_occurrencePersistenceServices.SpeciesByAmbient()
                .ToDictionary(x => Strings.ResourceManager.GetString(x.Key), x => x.Value.ToString()), Strings.Ambient, Strings.SpeciesPlural));
        }


        private ActionResult OccurrencesByConservationUnit()
        {
            return PartialView("DisplayTemplates/DictionaryTable", new DictionaryTable(_occurrencePersistenceServices.OccurrencesByConservationUnit()
                .ToDictionary(x => x.Key, x => x.Value.ToString()), Strings.ConservationUnit, Strings.Occurrences));
        }

        private ActionResult OccurrencesByMonthYear()
        {
            return PartialView("DisplayTemplates/DictionaryTable", new DictionaryTable(_occurrencePersistenceServices.OccurrencesByMonthYear(), Strings.MonthYear, Strings.Occurrences));
        }

        private StatisticsPageModel CreateStatisticsPageModel()
        {
            ViewData["FirstColumnWidth"] = 200;
            return new StatisticsPageModel(
                _sinbiotaStatistics.NumberOfProjects(), _sinbiotaStatistics.NumberOfUsers(),
                _occurrencePersistenceServices.NumberOfAuthors(),
                _occurrencePersistenceServices.NumberOfTaxonomicGroups(),
                _occurrenceStatistics.TotalOccurrences(),
                _speciesStatistics.TotalSpecies());
        }


        private ActionResult OccurrencesByTaxonomicGroup()
        {
            var d = _occurrencePersistenceServices.OccurrencesByTaxonomicGroup().ToDictionary(x => x.Key, x => x.Value.ToString());
            return PartialView("DisplayTemplates/DictionaryTable", new DictionaryTable(d, Strings.TaxonomicGroup, Strings.Occurrences));
        }

        private ActionResult OccurrencesByMunicipality()
        {
            var d = _occurrencePersistenceServices.OccurrencesByMunicipality().ToDictionary(x => x.Key, x => x.Value.ToString());
            return PartialView("DisplayTemplates/DictionaryTable", new DictionaryTable(d, Strings.Municipality, Strings.Occurrences));
        }

        private ActionResult OccurrencesByDrainageBasin()
        {
            var d = _occurrencePersistenceServices.OccurrencesByDrainageBasin().ToDictionary(x => x.Key, x => x.Value.ToString());
            return PartialView("DisplayTemplates/DictionaryTable", new DictionaryTable(d, Strings.DrainageBasin, Strings.Occurrences));
        }

        private ActionResult OccurrencesByAmbient()
        {
            var d = _occurrencePersistenceServices.OccurrencesByAmbient().ToDictionary(x => Strings.ResourceManager.GetString(x.Key), x => x.Value.ToString());
            return PartialView("DisplayTemplates/DictionaryTable", new DictionaryTable(d, Strings.Ambient, Strings.Occurrences));
        }

    }
    public enum OccurrenceStatisticsType
    {
        OccurrencesByMonthYear,
        OccurrencesByAmbient,
        OccurrencesByDrainageBasin,
        OccurrencesByMunicipality,
        OccurrencesByTaxonomicGroup,
        OccurrencesByConservationUnit
    }
    public enum SpeciesStatisticsType
    {
        SpeciesByMonthYear,
        SpeciesByAmbient,
        SpeciesByDrainageBasin,
        SpeciesByMunicipality,
        SpeciesByTaxonomicGroup,
        SpeciesByConservationUnit,
        Top10Species,
    }

}
